/**
*  \file endian_write.h
*
*  \brief write integer values to address considering the byte order.
*
*  \author Jianshui Hong
*
*
*/
#ifndef ENDIAN_WRITE_H_INCLUDED
#define ENDIAN_WRITE_H_INCLUDED

/*================================================[ public includes  ]================================================*/
#include "../cfg/prj.h"
#include "../pal/pal.h"
/*================================================[ public defines   ]================================================*/

/*================================================[ public datatypes ]================================================*/

/*================================================[ public variables ]================================================*/

/*================================================[ inline functions ]================================================*/

/*=======================================================[ U16 ]======================================================*/

/** write U16 with big endian
*
*	This function write a variable that located on an arbitrarily address, considering the byte order.
*
* 	\param adr Pointer to address to write to.
*
*   \param value write value to address
*/
STATIC_INLINE void endian_write_u16_big(void* adr, U16 value )

{
#if PAL_ENDIAN == PAL_ENDIAN_LITTLE
   pal_memcpy_reverse_2(adr,&value);
#else
   pal_memcpy_2(adr,&value);
#endif
}


/** write U16 with little endian to address
*
*
* 	\param adr Pointer to address to write to
*
*   \param value write value to address
*/
STATIC_INLINE void endian_write_u16_little(void* adr, U16 value  )
{
#if PAL_ENDIAN == PAL_ENDIAN_LITTLE
	pal_memcpy_2(adr,&value);
#else
	pal_memcpy_reverse_2(adr,&value);
#endif
}

/*=======================================================[ S16 ]======================================================*/
/** write S16 with big endian to address
*
*
* 	\param adr Pointer to address to write to
*
*   \param value write value to address
*/

STATIC_INLINE void endian_write_s16_big(void* adr, S16 value  )
{
#if PAL_ENDIAN == PAL_ENDIAN_LITTLE
	pal_memcpy_reverse_2(adr,&value);
#else
	pal_memcpy__2(adr,&value);
#endif
}

/** write S16 with little endian to address
*
*
* 	\param adr Pointer to address to write to
*
*   \param value write value to address
*/
STATIC_INLINE void endian_write_s16_little(void* adr, S16 value  )
{
#if PAL_ENDIAN == PAL_ENDIAN_LITTLE
	pal_memcpy_2(adr,&value);
#else
	pal_memcpy_reverse_2(adr,&value);
#endif
}



/*=======================================================[ U32 ]======================================================*/
/** write U32 with big endian to address
*
*
* 	\param adr Pointer to address to write to
*
*
*   \param value write value to address
*/
STATIC_INLINE void endian_write_u32_big(void* adr, U32 value  )
{
#if PAL_ENDIAN == PAL_ENDIAN_LITTLE
	pal_memcpy_reverse_4(adr,&value);
#else
	pal_memcpy_4(adr,&value);
#endif
}
/** write U32 with little endian to address
*
*
* 	\param adr Pointer to address to write to
*
*   \param value write value to address
*/

STATIC_INLINE void endian_write_u32_little(void* adr, U32 value  )
{
#if PAL_ENDIAN == PAL_ENDIAN_LITTLE
	pal_memcpy_4(adr,&value);
#else
	pal_memcpy_reverse_4(adr,&value);
#endif
}

/*=======================================================[ S32 ]======================================================*/

/** write S32 with big endian to address
*
*
* 	\param adr Pointer to address to write to
*
*   \param value write value to address
*/

STATIC_INLINE void endian_write_s32_big(void* adr, S32 value  )
{
#if PAL_ENDIAN == PAL_ENDIAN_LITTLE
	pal_memcpy_reverse_4(adr,&value);
#else
	pal_memcpy_4(adr,&value);
#endif
}

/** write S32 with little endian to address
*
*
* 	\param adr Pointer to address to write to
*
*   \param value write value to address
*/
STATIC_INLINE void endian_write_s32_little(void* adr, S32 value  )
{
#if PAL_ENDIAN == PAL_ENDIAN_LITTLE
	pal_memcpy_4(adr,&value);
#else
	pal_memcpy_reverse_4(adr,&value);
#endif
}

/*=======================================================[ U64 ]======================================================*/


#ifdef U64_MIN

/** write U64 with big endian to address
*
*
* 	\param adr Pointer to address to write to
*
*   \param value write value to address
*/
STATIC_INLINE void endian_write_u64_big(void* adr, U64 value  )
{
#if PAL_ENDIAN == PAL_ENDIAN_LITTLE
	pal_memcpy_reverse_8(adr,&value);
#else
	pal_memcpy_8(adr,&value);
#endif
}

/** write U64 with little endian to address
*
*
* 	\param adr Pointer to address to write to
*
*   \param value write value to address
*/
STATIC_INLINE void endian_write_u64_little(void* adr, U64 value  )
{
#if PAL_ENDIAN == PAL_ENDIAN_LITTLE
	pal_memcpy_8(adr,&value);
#else
	pal_memcpy_reverse_8(adr,&value);
#endif
}
#endif

/*=======================================================[ S64 ]======================================================*/
#ifdef S64_MIN

/** write S64 with big endian to address
*
*
* 	\param adr Pointer to address to write to
*
*   \param value write value to address
*/

STATIC_INLINE void endian_write_s64_big(void* adr, S64 value  )
{
#if PAL_ENDIAN == PAL_ENDIAN_LITTLE
	pal_memcpy_reverse_8(adr,&value);
#else
	pal_memcpy_8(adr,&value);
#endif
}

/** write S64 with little endian to address
*
*
* 	\param adr Pointer to address to write to
*
*   \param value write value to address
*/

STATIC_INLINE void endian_write_s64_little(void* adr, S64 value  )
{
#if PAL_ENDIAN == PAL_ENDIAN_LITTLE
	pal_memcpy_8(adr,&value);
#else
	pal_memcpy_reverse_8(adr,&value);
#endif
}

#endif


/*=======================================================[ F32 ]======================================================*/
#ifdef F32_MIN

/** write F32 with big endian to address
*
*
* 	\param adr Pointer to address to write to
*
*
*   \param value write value to address
*/

STATIC_INLINE void endian_write_f32_big(void* adr, F32 value  )
{
#if PAL_ENDIAN == PAL_ENDIAN_LITTLE
	pal_memcpy_reverse_4(adr,&value);
#else
	pal_memcpy_4(adr,&value);
#endif
}

/** write F32 with little endian to address
*
*
* 	\param adr Pointer to address to write to
*
*
*   \param value write value to address
*/

STATIC_INLINE void endian_write_f32_little(void* adr, F32 value  )
{
#if PAL_ENDIAN == PAL_ENDIAN_LITTLE
	pal_memcpy_4(adr,&value);
#else
	pal_memcpy_reverse_4(adr,&value);
#endif
}

#endif

/*=======================================================[ F64 ]======================================================*/
#ifdef F64_MIN

/** write F64 with big endian to address
*
*
* 	\param adr Pointer to address to write to
*
*
*   \param value write value to address
*/

STATIC_INLINE void endian_write_f64_big(void * adr, F64 value  )
{
#if PAL_ENDIAN == PAL_ENDIAN_LITTLE
	pal_memcpy_reverse_8(adr,&value);
#else
	pal_memcpy_8(adr,&value);
#endif
}

/** write F64 with little endian to address
*
*
* 	\param adr Pointer to address to write to
*
*
*   \param value write value to address
*/

STATIC_INLINE void endian_write_f64_little(void* adr, F64 value  )
{
#if PAL_ENDIAN == PAL_ENDIAN_LITTLE
	pal_memcpy_8(adr,&value);
#else
	pal_memcpy_reverse_8(adr,&value);
#endif
}

#endif




/*====================================================================================================================*/

#endif

/***********************************************************************************************************************
*                             Copyright 2018 Linde Material Handling. All rights reserved.                             *
***********************************************************************************************************************/
